package core.domain;

import java.io.Serializable;
import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Part implements Serializable {
	
	private static final long serialVersionUID = -8486207346240626293L;
	
	private Torrent parentTorrent;
	
	private int index;
	
	private List<String> payloadRows = null;
	
	private int partHash = -1; //invalid hash as initial

	public static enum PartStatus{OK,OUT_OF_BOUNDS, MISSING}
	
	private PartStatus partStatus = PartStatus.MISSING; //defaultly missing, by adding payload it is set to OK.
	
	public PartStatus getPartStatus() {
		return partStatus;
	}
	
	public void setPartStatus(PartStatus partStatus) {
		this.partStatus = partStatus;
	}
	
	public Part(int index, List<String> payloadRows) {
		super();
//		this.parentTorrent = parentTorrent; //Set it with setter!
		this.index = index;
		this.payloadRows = payloadRows;
		partHash = calulatePartHash(payloadRows);
		partStatus = partHash == -1 ? PartStatus.MISSING : PartStatus.OK;
	}

	public static int calulatePartHash(List<String> payloadRows2) {
		//TODO: clean up!
		if(payloadRows2 == null || payloadRows2.isEmpty())
			return -1;
		String eol = System.getProperty("line.separator");
		int result = 0;
		for(String row : payloadRows2){
			for(String c : row.trim().split("")){
				if(!c.equals(eol) && !c.isEmpty()){
					result += c.toCharArray()[0]; 
				}
			}
		}
		return result;
	}

	public Part() {
	}
	
	public Part(int index){
		this.index = index;
	}

	public Torrent getParentTorrent() {
		return parentTorrent;
	}

	public void setParentTorrent(Torrent parentTorrent) {
		this.parentTorrent = parentTorrent;
	}

	public int getIndex() {
		return index;
	}

	public void setIndex(int index) {
		this.index = index;
	}

	public List<String> getPayloadRows() {
		return payloadRows;
	}

	public void setPayloadRows(List<String> payloadRows) {
		this.payloadRows = payloadRows;
//		partHash = calulatePartHash(payloadRows); //caused initialization problems with serializations...
	}
	
	public int getPartHash() {
		return partHash;
	}
	
	public void setPartHash(int partHash) {
		this.partHash = partHash;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + index;
		result = prime * result + ((parentTorrent == null) ? 0 : parentTorrent.hashCode());
		result = prime * result + partHash;
		result = prime * result + ((payloadRows == null) ? 0 : payloadRows.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Part other = (Part) obj;
		if (index != other.index)
			return false;
		if (parentTorrent == null) {
			if (other.parentTorrent != null)
				return false;
		} else if (!parentTorrent.equals(other.parentTorrent))
			return false;
		if (partHash != other.partHash)
			return false;
		if (payloadRows == null) {
			if (other.payloadRows != null)
				return false;
		} else if (!payloadRows.equals(other.payloadRows))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Part [parentTorrent=" + parentTorrent + ", index=" + index + ", partHash=" + partHash + ", partStatus=" + partStatus + "]";
	}
	
}
